package com.jk.activiti.service.impl;


////import com.ruoyi.common.core.page.PageDomain;
////import com.ruoyi.common.core.page.TableSupport;
////import com.ruoyi.common.core.text.Convert;
////import com.ruoyi.common.utils.StringUtils;


import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jk.activiti.utils.Convert;
import com.jk.activiti.utils.StringUtils;
import com.jk.common.bean.PageHelper;
import com.jk.common.bean.Query;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntityImpl;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

@Transactional
@Service
public class ProcessDefinitionService {

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private RepositoryService repositoryService;

    /**
     * 分页查询流程定义文件
     * @return
     */
    public Page<com.jk.activiti.domain.ProcessDefinition> listProcessDefinition(Map parm) {

        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        processDefinitionQuery.orderByProcessDefinitionId().orderByProcessDefinitionVersion().desc();

        if (parm.get("name")!=null&&StringUtils.isNotBlank(parm.get("name")+"")) {
            processDefinitionQuery.processDefinitionNameLike("%" + parm.get("name") + "%");
        }
        if (parm.get("key")!=null&&StringUtils.isNotBlank(parm.get("key")+"")) {
            processDefinitionQuery.processDefinitionKeyLike("%" + parm.get("key") + "%");
        }
        if (parm.get("category")!=null&&StringUtils.isNotBlank(parm.get("category")+"")) {
            processDefinitionQuery.processDefinitionCategoryLike("%" +parm.get("category") + "%");
        }

        List<ProcessDefinition> processDefinitionList;

        processDefinitionList = processDefinitionQuery.list();
        List<com.jk.activiti.domain.ProcessDefinition> data = new ArrayList<>();
        for (ProcessDefinition definition: processDefinitionList) {
            ProcessDefinitionEntityImpl entityImpl = (ProcessDefinitionEntityImpl) definition;
            com.jk.activiti.domain.ProcessDefinition entity = new com.jk.activiti.domain.ProcessDefinition();
            entity.setId(definition.getId());
            entity.setKey(definition.getKey());
            entity.setName(definition.getName());
            entity.setCategory(definition.getCategory());
            entity.setVersion(definition.getVersion());
            entity.setDescription(definition.getDescription());
            entity.setDeploymentId(definition.getDeploymentId());
            Deployment deployment = repositoryService.createDeploymentQuery()
                    .deploymentId(definition.getDeploymentId())
                    .singleResult();
            entity.setDeploymentTime(deployment.getDeploymentTime());
            entity.setDiagramResourceName(definition.getDiagramResourceName());
            entity.setResourceName(definition.getResourceName());
            entity.setSuspendState(entityImpl.getSuspensionState() + "");
            if (entityImpl.getSuspensionState() == 1) {
                entity.setSuspendStateName("已激活");
            } else {
                entity.setSuspendStateName("已挂起");
            }
            data.add(entity);
        }

        Query query = new Query(parm);
        Page page = query.getPage();
        PageHelper.startPage(page);
        page.setRecords(data);
        return page;
    }

    public List<com.jk.activiti.domain.ProcessDefinition> getProcessDefinition(Map parm) {
        List<com.jk.activiti.domain.ProcessDefinition> data = new ArrayList<>();
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        processDefinitionQuery.orderByProcessDefinitionId().orderByProcessDefinitionVersion().desc();
        List<ProcessDefinition> processDefinitionList;
        processDefinitionList = processDefinitionQuery.list();
        for (ProcessDefinition definition: processDefinitionList) {
            ProcessDefinitionEntityImpl entityImpl = (ProcessDefinitionEntityImpl) definition;
            com.jk.activiti.domain.ProcessDefinition entity = new com.jk.activiti.domain.ProcessDefinition();
            entity.setId(definition.getId());
            entity.setKey(definition.getKey());
            entity.setName(definition.getName());
            entity.setCategory(definition.getCategory());
            entity.setVersion(definition.getVersion());
            entity.setDescription(definition.getDescription());
            entity.setDeploymentId(definition.getDeploymentId());
            Deployment deployment = repositoryService.createDeploymentQuery()
                    .deploymentId(definition.getDeploymentId())
                    .singleResult();
            entity.setDeploymentTime(deployment.getDeploymentTime());
            entity.setDiagramResourceName(definition.getDiagramResourceName());
            entity.setResourceName(definition.getResourceName());
            entity.setSuspendState(entityImpl.getSuspensionState() + "");
            if (entityImpl.getSuspensionState() == 1) {
                entity.setSuspendStateName("已激活");
            } else {
                entity.setSuspendStateName("已挂起");
            }
            data.add(entity);
        }

        return data;
    }


    public void deployProcessDefinition(String filePath) throws FileNotFoundException {
        if (StringUtils.isNotBlank(filePath)) {
            if (filePath.endsWith(".zip")) {
                ZipInputStream inputStream = new ZipInputStream(new FileInputStream(filePath));
                repositoryService.createDeployment()
                        .addZipInputStream(inputStream)
                        .deploy();
            } else if (filePath.endsWith(".bpmn")) {
                repositoryService.createDeployment()
                        .addInputStream(filePath, new FileInputStream(filePath))
                        .deploy();
            }
        }
    }

    public int deleteProcessDeploymentByIds(String deploymentIds) throws Exception {
        String[] deploymentIdsArr = Convert.toStrArray(deploymentIds);
        int counter = 0;
        for (String deploymentId: deploymentIdsArr) {
            List<ProcessInstance> instanceList = runtimeService.createProcessInstanceQuery()
                    .deploymentId(deploymentId)
                    .list();
            if (!CollectionUtils.isEmpty(instanceList)) {
                // 存在流程实例的流程定义
                throw new Exception("删除失败，存在运行中的流程实例");
            }
            repositoryService.deleteDeployment(deploymentId, true); // true 表示级联删除引用，比如 act_ru_execution 数据
            counter++;
        }
        return counter;
    }

    public void suspendOrActiveApply(String id, String suspendState) {
        if ("1".equals(suspendState)) {
            // 当流程定义被挂起时，已经发起的该流程定义的流程实例不受影响（如果选择级联挂起则流程实例也会被挂起）。
            // 当流程定义被挂起时，无法发起新的该流程定义的流程实例。
            // 直观变化：act_re_procdef 的 SUSPENSION_STATE_ 为 2
            repositoryService.suspendProcessDefinitionById(id);
        } else if ("2".equals(suspendState)) {
            repositoryService.activateProcessDefinitionById(id);
        }
    }

}
